/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gui;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;
import java.util.Random;
import java.util.Set;
import javax.swing.*;
import model.Pion;

/**
 *
 * @author Benjamin De Clercq, Michiel Vancoillie, Ruben Slabbinck
 */
public class Bord extends JPanel implements MouseListener {

    static final Color KLEUR_VELD = new Color(0, 100, 0);
    static final Color KLEUR_MOERAS = new Color(70, 130, 180);
    
    static final int COMPUTER = 1;
    static final int SPELER = 2;
    private final int DIMENSIE = 10;

    private int currentSpeler = SPELER;
    private boolean pauzed = true;
    private Vak[][] vakken;
    private Vak bron;
    private Vak doel;
    private Boolean pionGeselecteerd;
    private Random rnd = new Random();
    private KeuzePaneel keuzePaneelRood;
    private KeuzePaneel keuzePaneelBlauw;
    private List<Integer> directions = Arrays.asList(0, 1, 2, 3);

    public Bord() {
        super();

        setLayout(new GridLayout(DIMENSIE, DIMENSIE));
        setPreferredSize(new Dimension(600, 600));
        vakken = new Vak[DIMENSIE][DIMENSIE];
        for (int i = 0; i < DIMENSIE; i++) {
            for (int j = 0; j < DIMENSIE; j++) {
                if ((i > 3 && i < 6) && ((j > 1 && j < 4) || (j > 5 && j < 8))) {
                    vakken[i][j] = new Vak(i, j, KLEUR_MOERAS);
                } else {
                    vakken[i][j] = new Vak(i, j, KLEUR_VELD);
                }

                vakken[i][j].addMouseListener(this);
                add(vakken[i][j]);
            }
        }

        //TESTSITUATIE
        //fillRandomBoardForPlayer(SPELER, 6, 10);

        bron = null;
        pionGeselecteerd = false;
        pauzed = false;
    }

    public void fillRandomBoardForPlayer(int team, int beginregion, int endregion) {
        Set keySet = Pion.LEGER.keySet();
        ArrayList randomLeger = new ArrayList(keySet);
        Collections.shuffle(randomLeger);

        for (int i = beginregion; i < endregion; i++) {
            for (int j = 0; j < DIMENSIE; j++) {
                vakken[i][j].setPion(new Pion(Pion.LEGER.get(randomLeger.get(j + ((i - beginregion) * DIMENSIE))), team));
            }
        }

    }

    public void setKeuzePaneel(KeuzePaneel keuzePaneelRood) {
        this.keuzePaneelRood = keuzePaneelRood;
    }

    public void setKeuzePaneel(KeuzePaneel keuzePaneelRood, KeuzePaneel keuzePaneelBlauw) {
        this.keuzePaneelRood = keuzePaneelRood;
        this.keuzePaneelBlauw = keuzePaneelBlauw;
    }

    public void mousePressed(MouseEvent e) {
        if (!pauzed) {
            // Bord nog niet compleet: blauwe pionnen plaatsen
            if (keuzePaneelBlauw.aantalPionnenResterend() > 0) {
                pionnenZetten(e,keuzePaneelBlauw);
            }

            // Bord nog niet compleet: rode pionnen plaatsen
            if (keuzePaneelRood.aantalPionnenResterend() > 0) {
                pionnenZetten(e, keuzePaneelRood);
            }

            // Bord compleet: starten
            if (keuzePaneelRood.aantalPionnenResterend() == 0) {
                currentSpeler = SPELER;
                // Selectie bron
                if (e.getButton() == 1) {
                    if (!pionGeselecteerd && ((Vak) e.getSource()).bezitPion() && (((Vak) e.getSource()).getPion()).getSpeler() == SPELER) {
                        bron = (Vak) e.getSource();
                        bron.selecteer();
                        pionGeselecteerd = true;
                    } else if (pionGeselecteerd && ((Vak) e.getSource()).bezitPion()) {
                        bron.deselecteer();
                        bron = (Vak) e.getSource();
                        bron.selecteer();
                    }
                } // Selectie doel
                else if (e.getButton() == 3) {
                    if (pionGeselecteerd && ((Vak) e.getSource()).zetMogelijk()) {

                        doel = (Vak) e.getSource();

                        // Zet mogelijk
                        if (((Math.abs(doel.getXValue() - bron.getXValue()) <= bron.getPion().getAantalStappen()) &&
                                (Math.abs(doel.getYValue() - bron.getYValue()) == 0)) ||
                                ((Math.abs(doel.getYValue() - bron.getYValue()) <= bron.getPion().getAantalStappen()) &&
                                (Math.abs(doel.getXValue() - bron.getXValue()) == 0))) {



                            // Zet zonder gevecht
                            if (!((Vak) e.getSource()).bezitPion()) {
                                // Als de bron een verkenner bevat mogen er zich geen pionnen bevinden tussen bron en doel
                                if (bron.getPion().getRang() == 3) {
                                    if (verkennerZetMogelijk()) {
                                        doel.setPion(bron.getPion());
                                        doel.repaint();
                                        bron.deselecteer();
                                        bron.removePion();
                                        bron.repaint();
                                        pionGeselecteerd = false;
                                        bron = null;
                                        doel = null;
                                    }
                                } else {
                                    doel.setPion(bron.getPion());
                                    doel.repaint();
                                    bron.deselecteer();
                                    bron.removePion();
                                    bron.repaint();
                                    pionGeselecteerd = false;
                                    bron = null;
                                    doel = null;
                                }
                            } // Zet met gevecht
                            else if (((Vak) e.getSource()).bezitPion() && ((((Vak) e.getSource()).getPion()).getSpeler() != bron.getPion().getSpeler())) {

                                // Als de bron een verkenner bevat mogen er zich geen pionnen bevinden tussen bron en doel
                                if (bron.getPion().getRang() == 3) {
                                    if (verkennerZetMogelijk()) {
                                        leverSlag();
                                    }
                                } else {
                                    leverSlag();
                                }


                            }

                            //geeft beurt aan de pc
                            computerMove();
                        }
                    }
                }
            }
        }
    }

    private void computerMove() {
        if (!pauzed) {
            currentSpeler = COMPUTER;
            int i = rnd.nextInt(DIMENSIE);
            int j = rnd.nextInt(DIMENSIE);

            while (!vakken[i][j].bezitPion() || vakken[i][j].getPion().getSpeler() != COMPUTER || vakken[i][j].getPion().getAantalStappen() == 0) {
                i = rnd.nextInt(DIMENSIE);
                j = rnd.nextInt(DIMENSIE);
            }
            bron = vakken[i][j];




            Collections.shuffle(directions);
            doel = null;

            for (int m = 0; m < 4; m++) {
                System.out.println(directions.get(m));
                switch (directions.get(m)) {

                    case 0:
                        //naar boven
                        if (i > 0 && ((!vakken[i - 1][j].bezitPion() && vakken[i - 1][j].zetMogelijk()) || (vakken[i - 1][j].bezitPion() && vakken[i - 1][j].getPion().getSpeler() != COMPUTER))) {
                            doel = vakken[i - 1][j];
                            System.out.println("j1");
                            m = 4;
                        }

                        break;
                    case 1:
                        //naar beneden
                        if (i < (DIMENSIE - 1) && ((!vakken[i + 1][j].bezitPion() && vakken[i + 1][j].zetMogelijk()) || (vakken[i + 1][j].bezitPion() && vakken[i + 1][j].getPion().getSpeler() != COMPUTER))) {
                            doel = vakken[i + 1][j];
                            System.out.println("j2");
                            m = 4;
                        }
                        break;
                    case 2:
                        //naar links
                        if (j > 0 && ((!vakken[i][j - 1].bezitPion() && vakken[i][j - 1].zetMogelijk()) || (vakken[i][j - 1].bezitPion() && vakken[i][j - 1].getPion().getSpeler() != COMPUTER))) {
                            doel = vakken[i][j - 1];
                            System.out.println("j3");
                            m = 4;
                        }
                        break;
                    case 3:
                        //naar rechts
                        if (j < (DIMENSIE - 1) && ((!vakken[i][j + 1].bezitPion() && vakken[i][j + 1].zetMogelijk()) || (vakken[i][j + 1].bezitPion() && vakken[i][j + 1].getPion().getSpeler() != COMPUTER))) {
                            doel = vakken[i][j + 1];
                            System.out.println("j4");
                            m = 4;
                        }
                        break;
                }
            }


            //geen goeie pion gevonden, probeer opnieuw
            //computerMove();
            if (doel == null) {
                computerMove();
            } else {

                if (!doel.bezitPion()) {
                    doel.setPion(bron.getPion());
                    doel.repaint();
                    bron.deselecteer();
                    bron.removePion();
                    bron.repaint();
                    pionGeselecteerd = false;
                    bron = null;
                    doel = null;
                } else {
                    leverSlag();
                }
            }

        }
    }

    private boolean verkennerZetMogelijk() {
        int bronX = bron.getXValue();
        int bronY = bron.getYValue();
        int doelX = doel.getXValue();
        int doelY = doel.getYValue();

        boolean zetMogelijk = true;
        if (bronX - doelX == 0) {
            if (bronY < doelY) {
                for (int i = bronY + 1; i < doelY; i++) {
                    if (vakken[bronX][i].bezitPion()) {
                        zetMogelijk = false;
                    }
                }
            } else {
                for (int i = doelY + 1; i < bronY; i++) {
                    if (vakken[bronX][i].bezitPion()) {
                        zetMogelijk = false;
                    }
                }
            }
        } else if (bronY - doelY == 0) {
            if (bronX < doelX) {
                for (int i = bronX + 1; i < doelX; i++) {
                    if (vakken[i][bronY].bezitPion()) {
                        zetMogelijk = false;
                    }
                }
            } else {
                for (int i = doelX + 1; i < bronX; i++) {
                    if (vakken[i][bronY].bezitPion()) {
                        zetMogelijk = false;
                    }
                }
            }
        }
        return zetMogelijk;
    }

    private void leverSlag() {
        if (doel.getPion().getRang() != 0) {
            //wanneer een pion op een bom gaat staan gaat hij er aan tenzij hij een ontmijner is
            if (doel.getPion().getRang() == 1 && bron.getPion().getRang() != 4) {
                doodBron();
            } //de vlag en de spion winnen van iedereen wanneer ze zelf aanvallen
            else if (bron.getPion().getRang() == 0 || bron.getPion().getRang() == 2) {
                doodDoel();
            } //anders wordt het gevecht beslist op basis van de hoogste rang
            else if (bron.getPion().getRang() > doel.getPion().getRang()) {
                doodDoel();
            } else if (bron.getPion().getRang() < doel.getPion().getRang()) {
                doodBron();
            } else if (bron.getPion().getRang() == doel.getPion().getRang()) {
                doel.removePion();
                doel.repaint();
                bron.deselecteer();
                bron.removePion();
                bron.repaint();

            }

        } else {
            doodDoel();
            pauzed = true;
            if (currentSpeler == SPELER) {
                //Speler wint
                int result = JOptionPane.showConfirmDialog((Component) null, "YOU WIN", "STRATEGO", JOptionPane.DEFAULT_OPTION);

            } else {
                int result = JOptionPane.showConfirmDialog((Component) null, "YOU LOSE", "STRATEGO", JOptionPane.DEFAULT_OPTION);
            }
            Spel.quit();
        }
        pionGeselecteerd = false;
        bron = null;
        doel = null;
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mouseDragged(MouseEvent e) {
    }

    public void mouseMoved(MouseEvent e) {
    }

    private void pionnenZetten(MouseEvent e, KeuzePaneel keuzePaneel) {
        if (!((Vak) e.getSource()).bezitPion() && keuzePaneel.heeftKeuzeGemaakt()) {
            doel = (Vak) e.getSource();
            if (keuzePaneel.controleerGebied(doel.getXValue())) {
                doel.setPion(keuzePaneel.geefKeuze().getPion());
                doel.repaint();

                keuzePaneel.geefKeuze().minusOne();
                if (keuzePaneel.geefKeuze().getAantal() <= 0) {
                    keuzePaneel.geefKeuze().deselecteer();
                    keuzePaneel.overdrachtCompleet();
                }

            }
        }
    }

    private void doodDoel() {
        doel.setPion(bron.getPion());
        doel.repaint();
        bron.deselecteer();
        bron.removePion();
        bron.repaint();
    }

    private void doodBron() {
        bron.deselecteer();
        bron.removePion();
        bron.repaint();
    }
}
